#-*- coding: big5 -*-
from model import Chapter,Section,UnorderedList,BulletItem,Paragraph

dicBookComponentClassToNodeCreateFunctionName={
    Chapter:'createNodeH',
    Section:'createNodeH',
    Paragraph:'createNodeP',
    UnorderedList:'createNodeH',
    BulletItem:'createNodeP',
}

class PagedDocumentFileCreator:
    def __init__(self,book,abstractPagedDocument):
        self.book=book
        self.abstractPagedDocument=abstractPagedDocument
        self.lstAllBookComponent=[]
        
    def traverseBookCreatePagedDocument(self):
        self.recursiveAssignAllBookComponent(self.book.lstBookComponent)
        for bookComponent in self.lstAllBookComponent:
            strFunction=dicBookComponentClassToNodeCreateFunctionName[bookComponent.__class__]
            if not self.abstractPagedDocument.canAddNode():
                    self.abstractPagedDocument.createPage()
            strExec='self.abstractPagedDocument.%s("%s")'%(strFunction,bookComponent.strText)
            exec(strExec)
                
    def recursiveAssignAllBookComponent(self,lstBookComponent):
       if not lstBookComponent: return
       for bookComponent in lstBookComponent:
           if bookComponent.isLeaf():
               self.lstAllBookComponent.append(bookComponent)
           else:
               self.lstAllBookComponent.append(bookComponent)
               self.recursiveAssignAllBookComponent(bookComponent.lstBookComponent)

    def savePages(self,strDirectory):
        for i in range(self.abstractPagedDocument.getNumPage()):
            file=open(strDirectory+str(i),'wb')
            file.write(self.abstractPagedDocument.getPageString(i))
            file.close()

###
class AbstractPagedDocument:
    def __init__(self):
        self.clear()
        
    def clear(self):
        self.intMaxNumNode=3
        self.intNumNode=self.intMaxNumNode
        self.lstAbstractPage=[]
        
    def getNumPage(self):
        return len(self.lstAbstractPage)

    def canAddNode(self):
        if self.intNumNode>=self.intMaxNumNode:
            return False
        return True

    def createPage(self):
        self.intNumNode=0
        
    def createNodeP(self,strText):
        self.intNumNode+=1
        
    def createNodeH(self,strText):
        self.intNumNode+=1
        
    def getPageString(self,intPageIndex):
        strPageString=''
        for abstractNode in self.lstAbstractPage[intPageIndex].lstAbstractNode:
            strPageString+=abstractNode.getText()+'\n'
        print 'intPageIndex:%s'%intPageIndex
        print strPageString
        return strPageString
    
class PagedDocumentHtml(AbstractPagedDocument):
    def createPage(self):
        AbstractPagedDocument.createPage(self)
        self.lstAbstractPage.append(PageHtml())

    def createNodeP(self,strText):
        AbstractPagedDocument.createNodeP(self,strText)
        node=NodeHtmlP(strText)
        self.lstAbstractPage[-1].addNode(node)
        
    def createNodeH(self,strText):
        AbstractPagedDocument.createNodeH(self,strText)
        node=NodeHtmlH(strText)
        self.lstAbstractPage[-1].addNode(node)
        
    def getPageString(self,intPageIndex):
        strPageString='<html>\n<head>\n</head>\n<body>\n'
        for abstractNode in self.lstAbstractPage[intPageIndex].lstAbstractNode:
            strPageString+=abstractNode.getText()+'\n'
        strPageString+='</body>\n</html>\n'
        print 'intPageIndex:%s'%intPageIndex
        print strPageString
        return strPageString

class PagedDocumentText(AbstractPagedDocument):
    def createPage(self):
        AbstractPagedDocument.createPage(self)
        self.lstAbstractPage.append(PageText())

    def createNodeP(self,strText):
        AbstractPagedDocument.createNodeP(self,strText)
        node=NodeTextP(strText)
        self.lstAbstractPage[-1].addNode(node)
        
    def createNodeH(self,strText):
        AbstractPagedDocument.createNodeH(self,strText)
        node=NodeTextH(strText)
        self.lstAbstractPage[-1].addNode(node)
    
###
class AbstractPage:
    def __init__(self):
        self.lstAbstractNode=[]

    def addNode(self,abstractNode):
        self.lstAbstractNode.append(abstractNode)
    
class PageHtml(AbstractPage):
    pass

class PageText(AbstractPage):
    pass
   
###
class AbstractNode:
    def __init__(self,strText):
        self.strText=strText

    def getText(self):
        return self.strText
###
class AbstractNodeP(AbstractNode):
    def __init__(self,strText):
        AbstractNode.__init__(self,strText)
    
class NodeHtmlP(AbstractNodeP):
    def __init__(self,strText):
        self.strText='<p>%s</p>'%strText
    
class NodeTextP(AbstractNodeP):
    def __init__(self,strText):
        self.strText='    %s'%strText
    
###
class AbstractNodeH(AbstractNode):
    def __init__(self,strText):
        AbstractNode.__init__(self,strText)
    
class NodeHtmlH(AbstractNodeH):
    def __init__(self,strText):
        self.strText='<h3>%s</h3>'%strText
    
class NodeTextH(AbstractNodeH):
    def __init__(self,strText):
        self.strText='%s'%strText
    
     